package com.gxjtkyy.datadistributer.writer.rdbms.util;

import com.gxjtkyy.datadistributer.common.exception.ColumnParseException;
import com.gxjtkyy.datadistributer.common.util.DateTimeUtil;
import com.gxjtkyy.datadistributer.common.util.FieldParserUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.Map;

/**
 * @description:
 * @author: tanhaichao
 * @create: 2024/10/25 10:05
 **/
public class FieldParserNewUtil {
    private static final Logger log = LoggerFactory.getLogger(FieldParserUtil.class);
    private static final String NO_FILL = "no_fill";
    public static final DateTimeFormatter FORMATTER_DATE = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    public static final DateTimeFormatter FORMATTER_TIME = DateTimeFormatter.ofPattern("HH:mm:ss");
    public static final DateTimeFormatter FORMATTER_DATETIME = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

//    private FieldParserUtil() {
//    }

    public static Object parseColumnValue(Integer columnType, String columnEncode, String rawValue, boolean isNumber) {
        try {
            return parseColumnValueInternal(columnType, columnEncode, rawValue, isNumber);
        } catch (Exception var4) {
            throw new ColumnParseException("解析字段时发生异常", var4);
        }
    }



    public static Object parseColumnValueInternal(Integer columnType, String columnEncode, String rawValue, boolean isNumber) {
        if ("no_fill".equals(rawValue)) {
            return null;
        } else {
            switch(columnType) {
                case 0:
                    return rawValue;
                case 1:
                case 16:
                case 23:
                case 24:
                case 38:
                case 39:
                    if (StringUtils.isBlank(rawValue)) {
                        return null;
                    } else {
                        if ("base64".equalsIgnoreCase(columnEncode)) {
                            return decodeBase64ToString(rawValue);
                        } else if (isNumber) {
                            return new BigDecimal(rawValue);
                        }
                        return rawValue;
                    }
                case 2:
                case 3:
                case 4:
                case 5:
                case 14:
                case 25:
                    if (StringUtils.isBlank(rawValue)) {
                        return null;
                    } else if ("NULL".equalsIgnoreCase(rawValue)) {
                        return null;
                    } else {
                        if ("base64".equalsIgnoreCase(columnEncode)) {
                            return Long.valueOf(decodeBase64ToString(rawValue));
                        }

                        return Long.valueOf(rawValue);
                    }
                case 6:
                case 7:
                case 8:
                    if (StringUtils.isBlank(rawValue)) {
                        return null;
                    } else if ("NULL".equalsIgnoreCase(rawValue)) {
                        return null;
                    } else {
                        if ("base64".equalsIgnoreCase(columnEncode)) {
                            return Double.valueOf(decodeBase64ToString(rawValue));
                        }

                        return Double.valueOf(rawValue);
                    }
                case 9:
                    if (StringUtils.isBlank(rawValue)) {
                        return null;
                    } else if ("NULL".equalsIgnoreCase(rawValue)) {
                        return null;
                    } else {
                        if ("base64".equalsIgnoreCase(columnEncode)) {
                            return DateTimeUtil.strToLocalDate(decodeBase64ToString(rawValue));
                        }

                        return DateTimeUtil.strToLocalDate(rawValue);
                    }
                case 10:
                    if (StringUtils.isBlank(rawValue)) {
                        return null;
                    } else if ("NULL".equalsIgnoreCase(rawValue)) {
                        return null;
                    } else {
                        if ("base64".equalsIgnoreCase(columnEncode)) {
                            return DateTimeUtil.strToLocalTime(decodeBase64ToString(rawValue));
                        }

                        return DateTimeUtil.strToLocalTime(rawValue);
                    }
                case 11:
                    if (StringUtils.isBlank(rawValue)) {
                        return null;
                    } else if ("NULL".equalsIgnoreCase(rawValue)) {
                        return null;
                    } else {
                        if ("base64".equalsIgnoreCase(columnEncode)) {
                            return DateTimeUtil.strToLocalDateTime(decodeBase64ToString(rawValue));
                        }

                        return DateTimeUtil.strToLocalDateTime(rawValue);
                    }
                case 15:
                    if (StringUtils.isBlank(rawValue)) {
                        return null;
                    }

                    return decodeBase64ToString(rawValue);
                case 101:
                    throw new UnsupportedOperationException();
                case 102:
                    if (StringUtils.isBlank(rawValue)) {
                        return null;
                    }

                    return decodeBase64ToBuffer(rawValue);
                default:
                    log.error("Unknown field type: {}", columnType);
                    throw new ColumnParseException(String.format("Unknown field type: %s", columnType));
            }
        }
    }

    public static String parseColumnValueAsString(Integer columnType, String columnEncode, String rawValue) {
        Object value = parseColumnValue(columnType, columnEncode, rawValue, false);
        if (value == null) {
            return null;
        } else if (value instanceof LocalDateTime) {
            return FORMATTER_DATETIME.format((LocalDateTime)value);
        } else if (value instanceof LocalDate) {
            return FORMATTER_DATE.format((LocalDate)value);
        } else if (value instanceof LocalTime) {
            return FORMATTER_TIME.format((LocalTime)value);
        } else {
            return value instanceof byte[] ? Base64.getEncoder().encodeToString((byte[])value) : value.toString();
        }
    }

    public static byte[] decodeBase64ToBuffer(String base64Str) {
        return base64Str.isBlank() ? null : Base64.getDecoder().decode(base64Str);
    }

    public static String decodeBase64ToString(String base64Str) {
        try {
            if (base64Str.isBlank()) {
                return "";
            } else {
                byte[] buf = Base64.getDecoder().decode(base64Str);
                return new String(buf, "GB2312");
            }
        } catch (Throwable var2) {
            throw new RuntimeException(var2);
        }
    }
}
